<script lang="ts" setup>
import { computed, nextTick, useTemplateRef } from 'vue';
import { useRouter } from 'vue-router';
import { useFetch } from '@/mobile/hooks/fetch';
import { useAsyncData } from '@/mobile/hooks/async-data';
import { useTitleForClient } from '@/mobile/hooks/browser';
import { useI18n } from 'vue-i18n';
import { useWeChatShare } from '@/mobile/hooks/wechat-share';
import SidePanel from './components/SidePanel.vue';
import markdownIt from 'markdown-it';
import SanitizeHtml from '@/common/components/sanitize-html/index.vue';

import Prism from 'virtual:prismjs';

const props = defineProps({
  id: {
    type: String,
    default: '',
  },
  pageType: {
    type: String,
    default: 'detail',
  },
});

const { $fetch } = useFetch();
const router = useRouter();
const { setTitle } = useTitleForClient();
const { t } = useI18n();
const contentRef = useTemplateRef('contentEl');
const { setShareData } = useWeChatShare();

const generateTitle = (title: string) => `${title} - ${t('mobile.content.title2')}`;

const renderHighlight = () => {
  nextTick(() => {
    const el = contentRef.value?.getElement();

    if (el) {
      Prism.highlightAllUnder(el);
    }
  });
};

const { data: artCount } = useAsyncData(
  'mobile:detail',
  () => $fetch('/information/like/num', { data: { informationId: props.id } }),
  {
    cache: false,
    watch: [() =>  props.id],
  },
)

const { data: detail } = useAsyncData(
  'explore:journalism:detail',
  () => $fetch(props.pageType === 'preview' ? '/information/preview' : '/information/view', { data: { id: props.id } }),
  {
    cache: false,
    watch: [() =>  props.id],
    onAfterHandle({ handleSuccess, serverContext }) {
      if (serverContext) {
        if (handleSuccess && detail.value) {
          serverContext.title = generateTitle(detail.value.informationTitle);
          serverContext.description = detail.value.informationMsg;
          serverContext.keywords = detail.value.informationKeywords;
        }
        else {
          // 如果请求出错直接服务器重定向到 404 页面
          serverContext.redirect = '/404';
        }
      }
      else {
        if (handleSuccess && detail.value) {
          if (window.wx) {
            setShareData({ title: detail.value.informationTitle, desc: detail.value.informationMsg, img: detail.value.coverUrl })
          }
          setTitle(generateTitle(detail.value.informationTitle));
          renderHighlight();
        }
        else {
          router.replace('/404');
        }
      }
    },
  },
);

const labelList = computed(() => {
  return detail.value?.labelVOList || [];
});

const getRenderedContent = (type: number, text: string) => {
  if (type == 1) {
    const md = markdownIt({
      breaks: true,
      linkify: false,
      typographer: false,
      html: true,
      highlight: function(str, lang) {
        if (lang) {
          return `<pre class="language-${lang}"><code>${str.replace(/</g, '&lt;').replace(/>/g, '&gt;')}</code></pre>`;
        }

        return '';
      },
    });

    return md.render(text ?? '');
  }
  else {
    return text;
  }
}
</script>

<template>
  <main class="page-explore-detail w-[100%] bg-hex-ffffff">

    <div v-if="detail" class="p-20 pb-0">
      <h1 class="break-anywhere text-22 color-[#1c1c28] font-normal leading-33">{{ detail.informationTitle }}</h1>

      <div class="mt-8 flex-y-center gap-16 text-12 color-[#8b8b8b] font-normal leading-16" v-if="artCount">
        <span>{{ detail.updateTime }}</span>
        <span>{{ $t('mobile.home.detail.read', { view: artCount.informationViews }) }}</span>
      </div>

      <SanitizeHtml
        class="detail-content line-numbers mt-16 min-h-300 break-anywhere color-[#222226]"
        :class="[detail.textType == 1 ? 'markdown-text' : 'rich-text']"
        :value="getRenderedContent(detail.textType, detail.informationContent)"
        :data-prismjs-copy="$t('common.prismjs.copy')"
        :data-prismjs-copy-error="$t('common.prismjs.copyError')"
        :data-prismjs-copy-success="$t('common.prismjs.copySuccess')"
        ref="contentEl"
      />

      <div class="mt-32 flex-y-center flex-wrap gap-16" v-if="labelList.length">
        <span v-for="(item, index) in labelList" :key="index" class="block h-24 w-auto rounded-4 bg-hex-fafafa px-16 py-4 text-center text-12 color-hex-8b8b8b font-normal leading-16">
          #{{ item.labelName }}
        </span>
      </div>
    </div>
    <SidePanel :id="props.id" />
  </main>
</template>

<style lang="scss" scoped>
.page-explore-detail {
  .detail-content:deep() {
    h1 {
      font-size: 22px;
    }

    h2 {
      font-size: 20px;
    }

    h1,
    h2 {
      margin-top: 48px;
      font-weight: 500;
    }

    ol,
    ul,
    menu {
      margin-top: 1em;
      margin-bottom: 1em;
      padding-left: 40px;
    }

    ol {
      list-style: decimal;
    }

    ul {
      list-style: disc;
    }

    p,
    section {
      margin-top: 1em;
      margin-bottom: 1em;
      color: #222226;
      font-weight: 400;
      font-size: 16px;
      line-height: 32px;
    }

    img {
      max-width: 100%;
    }

    table {
      td {
        border-color: gray;
        border-width: 1px;
      }
    }

    pre {
      overflow-x: auto;
    }
  }

  .detail-content.markdown-text:deep() {
    table {
      width: 100%;
    }
  }
}
</style>
